
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSDK API test</title>
</head>
<body>

<link rel="stylesheet" href="./res/rongcloud.css">
<a href="https://github.com/rongcloud/websdk-demo/blob/master/api-test.html" class="get-source">获取源码</a>

<style>
	body{
		font-size:14px;
		line-height:2;
		color:#333;
	}
	h1,h2,h3{
		margin:0;
	}
	.panel span{
		display:inline-block;	
		width:60px;
	}
	.show{
		display:none;
		font-size:12px;
		border:1px solid #ccc;
		background:#fff;
		padding:10px 30px;
		width:300px;
		overflow:auto;
		position:fixed;
		right:10px;
		top:0;
		bottom:10px;
	}
	.btns{
		display:none;
	}
	.btns input,
	.btns a{
		font-size:12px;
		margin:20px 10px 0 10px;
	}	
	.result{
		display:none;
		background:#f5f5f5;
		margin-top:30px;
		width:730px;
		padding:5px;
		overflow:hidden;
	}
	.result h2{
		font-size:14px;
		margin:0;
		padding:0;
	}
	.result btn{
		margin:5px;
		padding:0;
		color:#cd0000;
	}
	.result-code{
		float:right;
		margin:0 5px 5px 0;
		color:#fff;
		background:#000;
		border:none;
	}
	#result-body{
		position: relative;
	}
	.code-copy{
		position:absolute;
		right:5px;
		top:5px;
	}
	.title {
		background:#f5f5f5;
		padding-left:1em;
		padding-bottom:1em;
	}
	.title h2{
		display: inline;
		font-size:14px;
		margin-right:0.5em;
	}
</style>


<!-- 
check.js是做一些环境监测用的临时代码，仅限开发调试使用
-->
<!-- <script src="js/pre-check.js"></script> -->

<!-- 
http://www.ghostchina.com/adding-syntax-highlighting-to-ghost-using-highlight-js/
-->
<link href="res/monokai_sublime.min.css" rel="stylesheet">  
<script src="res/highlight.min.js"></script> 

<script type="text/javascript" src="lib/jquery-3.1.1.js"></script>
<link rel="stylesheet" href="json-view/jsonview.css" />
<script type="text/javascript" src="json-view/jquery.jsonview.js"></script>

<script src="//cdn.ronghub.com/RongIMLib-2.5.0.js"></script>
<script src="//cdn.ronghub.com/RongEmoji-2.2.4.min.js"></script> 
<script src="//cdn.ronghub.com/RongIMVoice-2.2.4.min.js"></script>

<!-- 声音样本文件 -->
<script src="res/voice-amr-base64.json"></script>

<!-- 二次封装的初始化代码 -->
<script src="init.js"></script>

<script>
"use strict";
function showTips(data){
	var dom = document.getElementById("show");
		dom.style.display = "block";
	if(data){
		dom.innerHTML += "<li>" + data + "</li>";
	}else{
		dom.innerHTML = "";
	}
}	
function showResult(title,code,start){
	var dom = document.getElementById("result-area");
		dom.style.display = "block";

	var now = new Date().getTime();
	var t = document.getElementById("result-title");
		t.innerHTML = title + '  <small>执行时间：'  + (now - start) + 'ms</small>';
	
	jsonOprators(code);
}

function jsonOprators(json){
	var jt = $('#result-body');

	if(typeof json == 'function'){
		jt.html('<pre class="jsonview"><code id="result-code">' + json + '</code></pre>');
		$('pre > code').each(function(i, block) {
			hljs.highlightBlock(block);
		});
	}else{
		json = JSON.stringify(json);
		jt.JSONView(json);
	}

	$('#collapse-btn').on('click', function() {
		jt.JSONView('collapse');
	});

	$('#expand-btn').on('click', function() {
		jt.JSONView('expand');
	});

	$('#toggle-btn').on('click', function() {
		jt.JSONView('toggle');
	});

	$('#toggle-level1-btn').on('click', function() {
		jt.JSONView('toggle', 1);
	});

	$('#toggle-level2-btn').on('click', function() {
		jt.JSONView('toggle', 2);
	});
}


function getTimer(begin){
	var now = new Date().getTime();
	return " time:" + (now - begin) + " ms";
}
</script>

<!-- 
用户数据，群组数据，好友关系 必须有应用服务器提供
显示会话信息需要从融云和应用服务器共同获取数据才能完整显示



开发环境 
	默认appkey = 8w7jv4qb78a9y，已上线
	当前用户：user8
	对象用户：user9,user10 

生产环境
	82hegw5uh8ktx
	rybznHwVbrk7upeAMWv8RnHEDKuqy0jJayFPsQ4gP8z+SyAuRRg4uk2hA24NDcnvbl6oswAYXQCdpAbHm4pp9g==
-->
<script>
"use strict";
var instance = null;
var appKey = "";
var token = "";

var userId = "";

/*
消息全部用单聊，user8 -> user9
*/
var conversationType = RongIMLib.ConversationType.PRIVATE; // 私聊
 /*
 PRIVATE 				1		单聊
 DISCUSSION 			2		讨论组
 GROUP 					3		群组
 CHATROOM 				4		聊天室
 CUSTOMER_SERVICE 		5		客服
 SYSTEM 				6		系统消息
 APP_PUBLIC_SERVICE 	7		应用公众账号（应用内私有）
 PUBLIC_SERVICE 		8		公众账号 (公有)
 */

var targetId = "user9"; 
var targetId2 = "user10";
var targetIds = [];
//消息接收方 Id，根据不同的 ConversationType，可能是用户 Id、讨论组 Id、群组 Id、聊天室 Id等。

var begin = 0;

function startInit(token){
	appKey = document.getElementById("appkey").value;

	if(appKey == ""){
		alert("必须提供appkey和token");
	}

	showTips();

	begin = new Date().getTime()

	//公有云初始化
	var config = {
		//protobuf: 'https://cdn.ronghub.com/protobuf-2.3.1.min.js' //支持http(s)网络路径、本地相对路径	
  };

    /*

		----------
		备注： 桌面版需优先开通，开通后方可使用
					开通方式，请移步开发者后台提工单，申请开通 https://developer.rongcloud.cn/signin?returnUrl=%2F
		----------

		RongDesktop 即为 electron-c++sdk/js/preload.js 中的 `RongDesktop`
		以下逻辑为 RongDesktop 存在即认为在 Electron 中，请一定保证 RongDesktop 唯一、不可破坏、不被污染
		详细请参考 init.js dataProvider 用法
    */
    var imClient = null;
	var isDesktopEnv = (typeof RongDesktop != 'undefined')
	if (isDesktopEnv) {
		imClient = RongDesktop.require('IMLib');
		// document.getElementById("rong-discussion").style.display = 'none';
		// document.getElementById("rong-public-service").style.display = 'none';
		// document.getElementById("rong-home-page").style.display = 'block';
	}

	var params = {
		appKey : appKey,
		token : token,
		imClient: imClient,
		userId: 'user10'
	};

	var callbacks = {
		getInstance : function(_instance){
			instance = _instance;
		},
		receiveNewMessage : function(message){
			// 判断消息类型
		    showTips("新消息，类型为：" + message.messageType);
            // showResult("新消息",message,start);

            console.log("messageUId:" + message.messageUId + ",   messageId:" + message.messageId);
            console.log(message);
		},
		getCurrentUser : function(userInfo){
			showTips("链接成功 用户id：" + userInfo.userId + ", 耗时" + getTimer(begin));
			userId = userInfo.userId;
			document.getElementById("login").innerHTML = userId;
		    afterConnected();
		}
	};
	init(params,callbacks,config);
	showTips("初始化 应用 " + getTimer(begin));


	RongIMLib.RongIMEmoji.init();
	showTips("初始化 表情库 " + getTimer(begin));


	RongIMLib.RongIMVoice.init();
	showTips("初始化 声音库 " + getTimer(begin));
}

function login(){
	token = document.getElementById("token").value;

	if(token == ""){
		alert("必须提供 token");
	}

	targetIds = document.getElementById("targetId").value;
	if(targetIds == ""){
		alert("必须提供两个的有效targetId");
	}

	targetIds = targetIds.split("，").join(",").split(",");
	targetId = targetIds[0];	
	targetId2 = targetIds[1];

	startInit(token);	
}

function changeUser(){
	instance.logout();
	var token = document.getElementById("token2").value;

	if(token == ""){
		alert("必须提供 token");
	}
	startInit(token);
}

function afterConnected(){
	document.getElementById("panel").style.display = "none";
	document.getElementById("btns").style.display = "block";
}

function disconnect(){
	/*
	文档：http://www.rongcloud.cn/docs/api/js/RongIMClient.html
	*/

	var start = new Date().getTime();
	instance.disconnect();
	showResult("断开链接 成功", null , start);
}

function reconnect(){
	/*
	1: reconnect 是重新连接，并没有重连机制，调用此方法前应该进行网络嗅探，网络正常再调用 reconnect。
	2: 提示其他设备登录请勿调用重连方法。
 	3: docs   http://www.rongcloud.cn/docs/api/js/RongIMClient.html
	*/

 	var start = new Date().getTime();
	begin = new Date().getTime();
	RongIMClient.reconnect({
		onSuccess: function(userId) {
			showTips("重新链接成功，用户id：" + userId + "; " + getTimer(begin));
			showResult("重新链接 成功", userId, start);
		},
		onTokenIncorrect: function() {
			//console.log('token无效');
			showResult("重新链接 失败", "token无效", start);
		},
		onError:function(errorCode){
		  var info = '';
		  switch (errorCode) {
		    case RongIMLib.ErrorCode.TIMEOUT:
		      info = '超时';
		      break;
		    case RongIMLib.ErrorCode.UNKNOWN_ERROR:
		      info = '未知错误';
		      break;
		    case RongIMLib.ErrorCode.UNACCEPTABLE_PROTOCOL_VERSION:
		      info = '不可接受的协议版本';
		      break;
		    case RongIMLib.ErrorCode.IDENTIFIER_REJECTED:
		      info = 'appkey不正确';
		      break;
		    case RongIMLib.ErrorCode.SERVER_UNAVAILABLE:
		      info = '服务器不可用';
		      break;
		  }
		  showTips(info);
		  showResult("重新链接 失败", info, start);
		}
	});
}

//消息撤回变量及设置
var recallMessage = null, clearMessage;
function markMessage(message){
	recallMessage = message;
	clearMessage = message;
}

function sendTextMessage(){
	/*
	文档： http://www.rongcloud.cn/docs/web.html#5_1、发送消息
		   http://rongcloud.cn/docs/api/js/TextMessage.html
	1: 单条消息整体不得大于128K
	2: conversatinType 类型是 number，targetId 类型是 string
	*/

	/*
		1、不要多端登陆，保证所有端都离线
		2、接收 push 设备设置:
			（1）打开系统通知提醒
			（2）小米设置 “授权管理” －> “自己的应用” 为自启动
			（3）应用内不要屏蔽新消息通知
		3、内置消息类型，默认 push，自定义消息类型需要
		   pushData 显示逻辑顺序：自定义 > 默认
		4、发送其他消息类型与发送 TextMessage 逻辑、方式一致
	*/
	var pushData = "pushData" + Date.now();

	var isMentioned = false;

	var content = {
		content: [
			"阿拉伯语：الشرق الأوسط ",
			"希伯来语：המזרח התיכון",
			"emoji: 😊 ",
			"希腊字母： π，α，β, ",
			"数字单位部分字符 如：× ",
			"拉丁文所有字符 如：Ο Ρ σ Ï Æ ",
			"拼音所有字符 如： ě ì ň ",
			"英文音标部分字符 如 ： ə ʃ ",
			"俄文部分字符 如 ：ш ; ⊇ â Œ Š ™ "
		].join(","),
		user : {
			"id" : "this-is-a-test-id",	//不支持中文及特殊字符
			"name" : "张三",
			"portrait" : "https://avatars1.githubusercontent.com/u/10265829?s=96&v=4"
		},
		extra: "{\"key\":\"value\", \"key2\" : 12, \"key3\":true}"
	};

	var msg = new RongIMLib.TextMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送文字消息 成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送文字消息 失败",message,start);
        }
    }, isMentioned, pushData);
}

function sendImageMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/api/js/ImageMessage.html

	需自行解决文件上传
	上传插件（含获取缩略图方法）: https://github.com/rongcloud/rongcloud-web-im-upload
	
	缩略图必须是base64码的jpg图，而且不带前缀"data:image/jpeg;base64,"，不得超过100K
	压缩：https://github.com/rongcloud/rongcloud-web-im-upload/blob/master/resize.html
	*/

	var content = {
		imageUri: "http://rongcloud.cn/images/newVersion/log_wx.png", 
		content: getBase64Image()
	};

	var msg = new RongIMLib.ImageMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送图片消息 成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送图片消息 失败",message,start);
        }
    });	
}

function sendFileMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/api/js/ImageMessage.html

	upload组件：https://github.com/rongcloud/rongcloud-web-im-upload
	上传插件文档: http://rongcloud.cn/docs/web.html#上传插件

	单条消息整体不得大于128K

	文件消息分两步：
		1、上传文件至文件服务器
		2、发送文件信息和文件 URL
	*/

	var content = {
	    name: 'log_wx', // 文件名称
	    size: '20k', // 文件大小，单位自己约定
	    type: 'png', // 文件的后缀名，例如 png、js、doc ...
	    fileUrl: 'http://rongcloud.cn/images/newVersion/log_wx.png' // 文件地址
	};

	var msg = new RongIMLib.FileMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送文件消息成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送文件消息失败",message,start);
        }
    });	
}

function sendVoiceMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/api/js/VoiceMessage.html

	需自行解决录音和转码问题，要求编码为base64格式amr，不带前缀，不得超过100K

	声音播放：https://rongcloud.github.io/websdk-demo/voice.html
	*/
	var content = {
		content : voice, //form res/voice-amr-base64.json
		duration : 20
	};
	
	var msg = new RongIMLib.VoiceMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送语音消息成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送语音消息失败",message,start);
        }
    });
}

function sendAtMessage(){
    /*
    @ 消息对象
    全部：RongIMLib.MentionedType.ALL；
    部分：RongIMLib.MentionedType.PART
	
	文档说明：http://support.rongcloud.cn/kb/NjE1
    接收@代码：https://rongcloud.github.io/websdk-demo/connect-check.html
    */
    var mentioneds = new RongIMLib.MentionedInfo();
	    mentioneds.type = RongIMLib.MentionedType.PART;
    	mentioneds.userIdList = [targetId, targetId2];

    var content = {
    	content: "This is a at message!",
    	extra: "extra info",
    	mentionedInfo: mentioneds
    };
	var msg = new RongIMLib.TextMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
		onSuccess: function (message) {
		   //message 为发送的消息对象并且包含服务器返回的消息唯一Id和发送消息时间戳
            showResult("发送 @ 消息成功",message,start);
		},
		onError: function (errorCode,message) {
            showResult("发送 @ 消息失败",message,start);
        }
	}, true);
}

function registerMessage(type,propertys){
	var messageName = type; // 消息名称。
	var objectName = "s:" + type; // 消息内置名称，请按照此格式命名 *:* 。
	var mesasgeTag = new RongIMLib.MessageTag(true,true); //true true 保存且计数，false false 不保存不计数。

	RongIMClient.registerMessageType(messageName,objectName,mesasgeTag,propertys);
}
function sendRegisterMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/web_api_demo.html#自定义消息

	注意事项：
		1：init之前注册新消息类型
		2：对应接收 onReceived: function (message) {}
			message.messageType == "PersonMessage"
		3：需要自己做解析实现
	*/
	var propertys = ["name","age","gender"]; // 消息类中的属性名。
	registerMessage("PersonMessage",propertys);

	var content = {
		name: {
			"first" : "Bob",
			"last" : "Smith"
		},
		age: 3,
		gender: "male"
	};

	var msg = new RongIMClient.RegisterMessage.PersonMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送自定义消息成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送自定义消息失败",message,start);
        }
    });
}

function sendLocationMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/api/js/LocationMessage.html

	缩略图必须是base64码的jpg图，而且不带前缀"data:image/jpeg;base64,"，不得超过100K

	需要自己做显示效果，一般显示逻辑：图片加链接，传入经纬度并跳转进入地图网站
	*/

	var content = {
		"content":getBase64Image(),
		"latitude":"24.114",
		"longitude":"334.221",
		"poi":"北京市朝阳区北苑路北辰泰岳大厦"
	};

	var msg = new RongIMLib.LocationMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送自定义消息成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送自定义消息失败",message,start);
        }
    });
}

function sendRichContentMessage(){
	/*
	http://www.rongcloud.cn/docs/api/js/RichContentMessage.html
	*/ 

	var content = {
		"title": "sendRichContentMessage",
		"content": "<a href=\"http://www.rongcloud.cn\">hello</a>",
		"imageUri": "http://www.demo.com/1.jpg",
		"url": "http://www.rongcloud.cn/",
		"extra": "{\"key\":\"value\"}"
	};

	var msg = new RongIMLib.RichContentMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送图文消息成功", message, start);
        },
        onError: function (errorCode,message) {
            showResult("发送图文消息失败", message, start);
        }
    });
}

function SendSyncReadStatusMessage(){
	/*
	一端发送，其他端接受并做同步更新
	具体处理说明文档： http://support.rongcloud.cn/kb/NjE0
	*/ 
	var sentTime = 1486975569605;// message 的 sentTime 服务器端时间
	var content = {
		lastMessageSendTime: sentTime
	};
	var msg = new RongIMLib.SyncReadStatusMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
            showResult("发送同步消息成功", message, start);
        },
        onError: function (errorCode,message) {
            showResult("发送同步消息失败", message, start);
        }
    });	
}

function sendRecallMessage(){
	if(recallMessage == null){
		alert("请先发送任意一条消息会再执行撤回");
		return;
	}
	//消息撤回服务器端没有时间限制，由客户端决定

	var start = new Date().getTime();
	instance.sendRecallMessage(recallMessage, {
        onSuccess: function (message) {
            showResult("撤回成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("撤回失败",message,start);
        }
    });		
}

function checkUnreadMessage(){
	/*
	http://www.rongcloud.cn/docs/web.html#5_5、检测是否有未读的消息

	此接口必须在init()方法之后调用，但不依赖于connect
	只返回true/false，不返回具体的未读数量
	若连接成功后调用此方法将一直返回 false。
	*/
	
	var start = new Date().getTime();
	instance.hasRemoteUnreadMessages(token,{
	    onSuccess:function(hasMessage){
	        if(hasMessage){
	            // 有未读的消息
	        }else{
	            // 没有未读的消息
	        }

            showResult("检查未读消息成功",hasMessage,start);

	    },onError:function(err){
            showResult("检查未读消息失败",err,start);
	    }
	});
}

function getHistroyMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/web_api_demo.html#获取历史消息

	注意事项：
		1：一定一定一定要先开通 历史消息云存储 功能，本服务收费，测试环境可免费开通
		2：登录开发者后台可以直接开启 https://developer.rongcloud.cn/app
		2：timestrap第二次拉取必须为null才能实现循环拉取
	*/

	var count = 3;  // 2 <= count <= 20
	var timestrap = null; //0, 1483950413013

	var start = new Date().getTime();
	instance.getHistoryMessages(conversationType, targetId, timestrap, count, {
		onSuccess: function(list, hasMsg) {
			//可通过sort订制其他顺序
			list.sort(function(a,b){
				return a.sentTime < b.sentTime;
			});

            showResult("获取历史消息成功",list,start);
		},
		onError: function(error) {
            showResult("获取历史消息失败",error,start);
		}
	});
} 


function clearHistroyMessage(){
	/*
		文档：http://www.rongcloud.cn/docs/web_api_demo.html#会话接口

		注意事项：必须开通历史消息云存储

		参数说明：
		timestamp 取值范围:  timestamp >=0 并且 timestamp <= 当前会话最后一条消息的 sentTime
 	*/
	if (!clearMessage) {
		alert('请先发一条消息');
		return;
	}
	var start = new Date().getTime();
	var params = {
		conversationType: clearMessage.conversationType,
		targetId: clearMessage.targetId,
		timestamp: clearMessage.sentTime
	};
	instance.clearRemoteHistoryMessages(params, {
		onSuccess: function() {
            showResult("清除历史消息成功", "success");
		},
		onError: function(error) {
			console.log('请排查： 历史消息云存储是否开通');
            showResult("清除历史消息失败",error);
		}
	});
} 

function getConversationList(){	
	/*
	文档：http://www.rongcloud.cn/docs/web_api_demo.html#会话接口
		http://www.rongcloud.cn/docs/web.html#5_2、同步会话列表
		http://www.rongcloud.cn/docs/api/js/Conversation.html

	历史消息云存储开通位置：https://developer.rongcloud.cn/service/roam/rXxI4IAJjxRAD72SpQ==

	注意事项：
		1：一定一定一定要先开通 历史消息云存储 功能，本服务收费，测试环境可免费开通
		2：只有发过消息才能生成会话
	*/

	var conversationTypes = null;  //具体格式设置需要补充
	var limit = 150; //获取会话的数量，不传或传null为全部，暂不支持分页
	var start = new Date().getTime();
	instance.getConversationList({
		onSuccess: function(list) {
			// list.sort(function(a,b){
			// 	return a.sentTime > b.sentTime;
			// });

			var title = "成功获取 " + list.length + " 个会话";
            showResult(title,list,start);
		},
		onError: function(error) {
            showResult("获取会话失败",error,start);
		}
    }, conversationTypes, limit);
}

function getConversation(){
	//需在 getConversationList 方法执行之后执行，否则返回null
	var start = new Date().getTime();

	instance.getConversation(conversationType, targetId, { 
		onSuccess:function(result){ 
            showResult("获取群组会话 成功", result, start);
		}, 
		onError:function(error){ 
		    showResult("获取群组会话 失败", error, start);
		} 
	});
}

function removeConversation(){
	var start = new Date().getTime();
	instance.removeConversation(conversationType, targetId, { 
		onSuccess:function(result){ 
            showResult("删除会话成功",result,start);
		}, 
		onError:function(error){ 
		// error => 清除会话错误码。 
		    showResult("删除会话失败",error,start);
		} 
	});
}

function clearConversation(){
	var start = new Date().getTime();
	instance.clearConversations({ 
		onSuccess:function(){ 
            showResult("清除会话成功",null,start);
		}, 
		onError:function(error){ 
		// error => 清除会话错误码。 
		    showResult("清除会话失败",error,start);
		} 
	});
}

function getUnreadCount(){
	/*
		阅读时间戳缓存在 localStorage 中，消息状态根据发送时间和阅读时间戳对比判断
		每次接受新消息后通过重新调用此方法计算
	 */
	var start = new Date().getTime();
	instance.getUnreadCount(conversationType,targetId,{
	    onSuccess:function(count){
	       showResult("获取会话未读数成功", count, start);
	    },
	    onError:function(error){
	       showResult("获取会话未读数失败", error, start);
	    }
	});
}

function getTotalUnreadCount(){
	/*
		阅读时间戳缓存在 localStorage 中，消息状态根据发送时间和阅读时间戳对比判断
		每次接受新消息后通过重新调用此方法计算
	 */
	var start = new Date().getTime();
	instance.getTotalUnreadCount({
	  onSuccess:function(count){
	       showResult("获取总未读数成功", count, start);
	  },
	  onError:function(error){
	      showResult("获取总未读数失败", error, start);
	  }
	});
}

function clearTotalUnreadCount(){
	var start = Date.now();
	instance.clearTotalUnreadCount({
	    onSuccess:function(){
	        showResult("清除未读总数成功", "success", start);
	    },
	    onError:function(error){
	        showResult("清除未读总数失败", error, start);
	    }
	});
}
function clearUnreadCount(){
	/*
	 	此方法清除当前端的未读数，并不会多端同步，
	 	多端同步需要发送 SyncReadStatusMessage：http://support.rongcloud.cn/kb/NjE0
	 */

	var start = Date.now();
	instance.clearUnreadCount(conversationType,targetId,{
	    onSuccess:function(){
	        showResult("清除指定会话未读数成功", "success", start);
	    },
	    onError:function(error){
	        showResult("清除指定会话未读数失败", error, start);
	    }
	});
}


function receiveMessage(){
	alert("请见init方法里的 RongIMClient.setOnReceiveMessageListener")
}


//加入聊天室后，可以用任意一个发送消息的方法发送消息，只需要conversationType为CHATROOM
var chatRoomId = "chatRoomId-008"; // 聊天室 Id,可任意指定，能区分不同聊天室即可
var count = 10; //拉取最近的会话内容（最多50条），-1不拉取 

function enterChatroom(){
	/*
	http://www.rongcloud.cn/docs/web_api_demo.html#聊天室

	聊天室不支持通过 getHistoryMessages 方法获取历史消息，

	count：//拉取最近的会话内容（最多50条），-1不拉取 
	*/

	var start = new Date().getTime();
	instance.joinChatRoom(chatRoomId, count, {
		onSuccess: function() {
            showResult("加入聊天室成功",null,start);
		},
		onError: function(error) {
            showResult("加入聊天室失败",null,start);
		}
	});
}

function quitChatroom(){
	var start = new Date().getTime();
	instance.quitChatRoom(chatRoomId, {
		onSuccess: function() {
            showResult("退出聊天室成功",null,start);
		},
		onError: function(error) {
            showResult("退出聊天室失败",null,start);
		}
	});
}

function getChatroomInfo(){
	/*
	需确认 当前用户 已加入聊天室
	*/ 
	var order = RongIMLib.GetChatRoomType.REVERSE;// 排序方式。
	var memberCount = 10; // 获取聊天室人数 （范围 0-20 ）

	var start = new Date().getTime();
	instance.getChatRoomInfo(chatRoomId, memberCount, order, {
	  onSuccess: function(chatRoom) {
			// chatRoom => 聊天室信息。
			// chatRoom.userInfos => 返回聊天室成员。
			// chatRoom.userTotalNums => 当前聊天室总人数。
            showResult("获取聊天室信息成功",chatRoom,start);
	  },
	  onError: function(error) {
            showResult("获取天室信息失败",error);
	  }
	});
}

function sendMessageToChatroom(){
	var content = {
		content:"hello，time：" + new Date().getTime(),
		extra:"RongCloud"
	};

	var conversationType = RongIMLib.ConversationType.CHATROOM; // 私聊
	var msg = new RongIMLib.TextMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(conversationType, chatRoomId, msg, {
        onSuccess: function (message) {
            showResult("发送聊天室消息成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送聊天室消息失败",message,start);
        }
    });
}

//发送题目
function sendQAMessage(){
	/*
	文档：http://www.rongcloud.cn/docs/web_api_demo.html#自定义消息

	注意事项：
		1：init之前注册新消息类型
		2：对应接收 onReceived: function (message) {}
			message.messageType == "PersonMessage"
		3：需要自己做解析实现
	*/
	var propertys = ["title","submitAPI","questions"]; // 消息类中的属性名。
	registerMessage("QA",propertys);

	var questions = [
		{
			id: 8560,
			question : "中国首都是那个城市？",
			answers : [{ id: 9901,answer: '上海', bingo: 9904},
					   { id: 9903,answer: '武汉', bingo: 9904 },
					   { id: 9904,answer: '北京', bingo: 9904 },
					   { id: 9905,answer: '深圳', bingo: 9904 }]
		},
		{
			id: 8561,
			question : "世界上最大的岛是那个？",
			answers : [{ id: 9906,answer: '马达加斯加', bingo: 9909},
					   { id: 9907,answer: '海南', bingo: 9909 },
					   { id: 9908,answer: '台湾', bingo: 9909 },
					   { id: 9909,answer: '格陵兰', bingo: 9909 }]
		},
		{
			id: 8562,
			question : "冰与火之歌里，那个家族的徽章是狼？",
			answers : [{ id: 9910,answer: '史塔克', bingo: 9910  },
					   { id: 9911,answer: '塔格利安', bingo: 9910 },
					   { id: 9912,answer: '兰尼斯特', bingo: 9910 }]
		},
		{
			id: 8563,
			question : "地球上最大的哺乳动物是？",
			answers : [{ id: 9913,answer: '鲸鱼', bingo: 9913 },
					   { id: 9914,answer: '大象', bingo: 9913 },
					   { id: 9915,answer: '巨蟒', bingo: 9913 },
					   { id: 9916,answer: '恐龙', bingo: 9913 }]
		},
		{
			id: 8564,
			question : "人们常说的花季是几岁？",
			answers : [{ id: 9917,answer: 15, bingo: 9920 },
					   { id: 9918,answer: 20, bingo: 9920 },
					   { id: 9919,answer: 18, bingo: 9920 },
					   { id: 9920,answer: 16, bingo: 9920 }]
		},
		{
			id: 8565,
			question : "成龙、林志颖、郭德纲最年轻的是谁？",
			answers : [{ id: 9921,answer: '成龙' , bingo: 9921},
					   { id: 9922,answer: '林志颖', bingo: 9921 },
					   { id: 9923,answer: '郭德纲', bingo: 9921 }]
		},
		{
			id: 8565,
			question : "劳动法规定，劳动者试用期不能超过几个月？",
			answers : [{ id: 9921,answer: 3 , bingo: 9921},
					   { id: 9922,answer: 6, bingo: 9921 },
					   { id: 9923,answer: 9, bingo: 9921 },
					   { id: 9924,answer: 12, bingo: 9921 }]
		},
		{
			id: 8566,
			question : "融云成立几年了？",
			answers : [{ id: 9921,answer: 4 , bingo: 9921},
					   { id: 9922,answer: 5, bingo: 9921 },
					   { id: 9923,answer: 3, bingo: 9921 },
					   { id: 9924,answer: 2, bingo: 9921 }]
		},
		{
			id: 8567,
			question : "变脸是我国哪个戏剧的绝活？",
			answers : [{ id: 9921,answer: '川剧' , bingo: 9921},
					   { id: 9922,answer: '京剧', bingo: 9921 },
					   { id: 9923,answer: '豫剧', bingo: 9921 },
					   { id: 9924,answer: '评剧', bingo: 9921 }]
		}
	];

	var qIndex = Math.floor(Math.random()*5);

	var content = {
		title: "冲顶大会",
		submitAPI: "http://abc.com/check",
		questions: JSON.stringify([questions[qIndex]])
	};

	var msg = new RongIMClient.RegisterMessage.QA(content);

	var start = new Date().getTime();
	var conversationType = RongIMLib.ConversationType.CHATROOM; // 私聊
	instance.sendMessage(conversationType, chatRoomId, msg, {
        onSuccess: function (message) {
        	markMessage(message);
            showResult("发送题目 成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("发送题目 失败",message,start);
        }
    });
}


/*
公众号
RongIMLib.ConversationType = {
	APP_PUBLIC_SERVICE : "应用服务平台 mc",
	PUBLIC_SERVICE : "公众服务平台 mp"
};
*/

var publicServiceType = RongIMLib.ConversationType.APP_PUBLIC_SERVICE; //固定值
var publicServiceId = "Rong_shuise"; //RongCloud
var searchType = 1; //[0-exact 1-fuzzy]
var keywords = "Rong";
// var keywords = "test";

/*
用户给公众号发消息
var conversationType = RongIMLib.ConversationType.PUBLIC_SERVICE;
var targetId = publicServiceId
*/

function sendToPublic(){
	/*
	文档： http://www.rongcloud.cn/docs/web.html#5_1、发送消息
		   http://rongcloud.cn/docs/api/js/TextMessage.html
	1: 单条消息整体不得大于128K
	2: conversatinType 类型是 number，targetId 类型是 string
	*/

	var content = {
		content: "公众号你好"
	};

	var msg = new RongIMLib.TextMessage(content);

	var start = new Date().getTime();
	instance.sendMessage(publicServiceType, publicServiceId, msg, {
        onSuccess: function (message) {
            showResult("公众号留言 成功",message,start);
        },
        onError: function (errorCode,message) {
            showResult("公众号留言 失败",message,start);
        }
    });
}

function getPublicHistroyMessage(){
	alert("暂不支持");

	// var count = 10;  // 2 <= count <= 20
	// var timestrap = null; //0, 1483950413013

	// var start = new Date().getTime();
	// instance.getHistoryMessages(publicServiceType, publicServiceId, timestrap, count, {
	// 	onSuccess: function(list, hasMsg) {
	// 	},
	// 	onError: function(error) {
	// 	}
	// });
} 

function getPublicServiceList(){
	/* 
	getRemotePublicServiceList = function (mpId, conversationType, pullMessageTime, callback)  
	*/ 
	var start = new Date().getTime();

	instance.getPublicServiceList({
	    onSuccess:function(list){
            showResult("获取已关注公众号 成功",list,start);
	    },
	    onError:function(error){
	    	showResult("搜索获取已关注公众号公众号 失败",error,start);
	    }
	});
}

function searchPublicService(){
	/*
	WebAPI文档：http://www.rongcloud.cn/docs/api/js/RongIMClient.html
	iOS文档：http://www.rongcloud.cn/docs/ios_imlib.html#公众服务
	*/ 
	var start = new Date().getTime();

	instance.searchPublicService(searchType, keywords, {
	    onSuccess:function(list){
            showResult("查找公众号 成功",list,start);
	    },
	    onError:function(error){
	    	showResult("查找公众号 失败",error,start);
	    }
	});
}

// function searchPublicServiceByType(){
// 	var start = new Date().getTime();

// 	instance.searchPublicServiceByType(publicServiceType, searchType, keywords, {
// 	    onSuccess:function(list){
//             showTips("搜索公众号by type 成功");
//             showResult("搜索公众号by type 成功",list,start);
// 	    },
// 	    onError:function(error){
// 	    	showTips("搜索公众号by type 失败");
// 	    	showResult("搜索公众号by type 失败",error,start);
// 	    }
// 	});
// }

function subscribePublicService(){
	/*
	http://www.rongcloud.cn/docs/api/js/RongIMClient.html

	*/
	var start = new Date().getTime();

	instance.subscribePublicService(publicServiceType, publicServiceId, {
	    onSuccess:function(list){
            showResult("订阅公众号 成功",list,start);
	    },
	    onError:function(error){
	    	showResult("订阅公众号 失败",error,start);
	    }
	});
}

function unsubscribePublicService(){
	/*
	http://www.rongcloud.cn/docs/api/js/RongIMClient.html
	
	*/
	var start = new Date().getTime();

	instance.unsubscribePublicService(publicServiceType, publicServiceId, {
	    onSuccess:function(list){
            showResult("取消订阅公众号 成功",list,start);
	    },
	    onError:function(error){
	    	showResult("取消订阅公众号 失败",error,start);
	    }
	});
}

function getPublicServiceProfile(){
	/*
	http://www.rongcloud.cn/docs/api/js/RongIMClient.html

	必须是已经关注的公众号，才能获取到详情
	*/
	var start = new Date().getTime();

	instance.getPublicServiceProfile(publicServiceType, publicServiceId, {
		onSuccess:function(profile){
            showResult("获取公众号详情 成功",profile,start);
		}, 
	  	onError:function(){
	  		cosnole.log("获取公众号详情 error");
	  	}
	});
}

//获取base64假数据方法
function getBase64Image(){
	var canvas = document.createElement("canvas");
		canvas.width = 100;
		canvas.height = 100;


	var context = canvas.getContext("2d");	
		context.font = "20pt Arial";    			
		context.fillStyle = "blue"; 
		context.fillText("RongCloud.cn", 10, 20);
	var content = canvas.toDataURL("image/jpeg");
		content = content.replace("data:image/jpeg;base64,","");
	return content;
}

function setUserStatus(){
	/*
		自定义在线状态(举例)：
		
		1、在线
			status : 10 

		2、离开
			status : 11 

		3、忙碌
			status : 12  

	*/
	var start = new Date().getTime();
	var status = 10;
	instance.setUserStatus(status, {
		onSuccess:function(status){
			// 此时别人 调用 setUserStatusListener 查询当前用户的在线状态 status 值为 10；
            showResult("设置在线状态成功", status, start);
		}, 
	  	onError:function(error){
	  		cosnole.log("设置在线状态 error:" + error);
	  	}
	});
}

function setUserStatusListener(){
	var start = new Date().getTime();
	var params =  {
		userIds: targetIds
	};
	// 批量获取用户信息，逐个返回
	instance.setUserStatusListener(params, function(userStatus){
		console.log(userStatus);
		/*
		userStatus 结构: {"status":[{"platform":["web"],"online":1,"status":10}],"userId":null}
		platform 平台: web | Android | iOS | pc
		online 在线标示: 1 | 0 , 1 表示在线，反之不在线 
		status 自定义状态, 通过 setUserStatus 设置
		*/
		showResult("获取用户在线状态成功", userStatus, start);
	});
}

</script>

<h1>Web SDK demo <small><a href="connect-check.html">消息接收demo</a></small></h1>
<button onclick="history.back()" style="display: none;" id="rong-home-page">主页</button>
<div class="panel" id="panel">
	<p>
		<span>appkey</span>
		<input type="text" id="appkey" size="20" value="8w7jv4qb78a9y">
	</p>
	<p>
		<span>token</span>
		<input type="text" id="token" size="90" _user="user10" value="4FGCL0oQ/E72nU4ivbui8uHR/ySxKaD1cAX2biXsYR6RsLYO9xAA4ooa+q3n42JnVTQyMAdFUiDsjFRDYZaQeg==">
		<!-- 
		8w7jv4qb78a9y
		user9	ZThhLI1Xa1BX5EMREAdArWSH6ouuI8NT/fNmMkzF+4IOKIoFvbsi6JnH8QmnSltLkCcsK8vOgKl3IZgfbxFiWg==
		user10	4FGCL0oQ/E72nU4ivbui8uHR/ySxKaD1cAX2biXsYR6RsLYO9xAA4ooa+q3n42JnVTQyMAdFUiDsjFRDYZaQeg== 
		user11	ovjkF2621YWp7odRhy9i6vHDlKxuUva3nL1owWyEuVOxBPB1/Pr1sY7ayEdnH2tgVyqC/Dcl95lDFEgeXzjaqQ==
		-->

		<!-- 
		82hegw5uh8ktx
		rybznHwVbrk7upeAMWv8RnHEDKuqy0jJayFPsQ4gP8z+SyAuRRg4uk2hA24NDcnvbl6oswAYXQCdpAbHm4pp9g==
		-->
	</p>
	<p>
		<span>token2</span>
		<input type="text" id="token2" size="90" _user="user11" value="ovjkF2621YWp7odRhy9i6vHDlKxuUva3nL1owWyEuVOxBPB1/Pr1sY7ayEdnH2tgVyqC/Dcl95lDFEgeXzjaqQ==">  &#160;&#160;<strong>切换方法使用</strong>
	</p>
	<p>
		<span>targetIds</span>
		<input type="text" id="targetId" size="25" value="user9,user8">
		<em>逗号间隔，至少提供两个</em>
	</p>
	<p>
		<span>&#160;</span>
		<input type="button" onclick="login()" value="初始化">  &#160;&#160;<strong>所有业务方法都必须在 链接成功 之后执行</strong>
	</p>
</div>

<div class="btns" id="btns">
	<div class="title">
		<h2>当前登录用户 id：<span id="login"></span></h2> 	
		<input type="button" value="切换用户" onclick="changeUser();">
	</div>

	链接状态：
	<input type="button" value="断开链接" onclick="disconnect();">
	<input type="button" value="重新链接" onclick="reconnect();">
	
	<br>


	发送消息：
	<input type="button" value="文字消息(携带用户信息)" onclick="sendTextMessage();">
	<input type="button" value="图片消息" onclick="sendImageMessage();">
	<input type="button" value="文件消息" onclick="sendFileMessage();">
	<input type="button" value="语音消息" onclick="sendVoiceMessage();">
	<br/>
	<input type="button" value="@ 消息" onclick="sendAtMessage();"> 
	<input type="button" value="富文本消息" onclick="sendRichContentMessage();">
	<input type="button" value="自定义消息" onclick="sendRegisterMessage();">
	<input type="button" value="位置消息" onclick="sendLocationMessage();"> 
	<input type="button" value="消息撤回" onclick="sendRecallMessage();"> 

	<br>

	接收消息：
	<input type="button" value="同步状态消息" onclick="SendSyncReadStatusMessage();">
	<input type="button" value="检查未读消息" onclick="checkUnreadMessage();"> 
	<input type="button" value="消息接收" onclick="receiveMessage();"> 
	
	<br>
	历史消息：
	<input type="button" value="获取列表" onclick="getHistroyMessage();"> 
	<input type="button" value="清空全部" onclick="clearHistroyMessage();"> 

	<br>

	会&nbsp;&nbsp;话：
	<input type="button" value="会话列表" onclick="getConversationList();">
	<input type="button" value="获取会话" title="需要在获取会话列表之后执行" onclick="getConversation();">
	<input type="button" value="会话未读数" onclick="getUnreadCount();"> 
	<input type="button" value="会话未读总数" onclick="getTotalUnreadCount();"> 
	<br/>
	<input type="button" value="清除会话未读数" onclick="clearUnreadCount();">
	<input type="button" value="清除全部未读数" onclick="clearTotalUnreadCount();">
	<input type="button" value="删除指定会话" onclick="removeConversation();">
	<input type="button" value="删除所有会话" onclick="clearConversation();">

	<br>

	聊 天 室：
	<input type="button" value="加入聊天室" onclick="enterChatroom();"> 
	<input type="button" value="聊天室发消息" onclick="sendMessageToChatroom();"> 
	<input type="button" value="聊天室发题目" onclick="sendQAMessage();"> 
	<input type="button" value="退出聊天室" onclick="quitChatroom();"> 
	<input type="button" value="获取聊天室信息" onclick="getChatroomInfo();"> 
	
	<br>
	
	在线状态：
	<input type="button" value="设置自己在线状态" onclick="setUserStatus();"> 
	<input type="button" value="查询其他人在线状态" onclick="setUserStatusListener();"> 
	<br>
	
	<div class="rong-public-service" id="rong-public-service">
		公众服务：
		<input type="button" value="获取已关注公众号" onclick="getPublicServiceList();"> 
		<input type="button" value="查找公众号" onclick="searchPublicService();"> 
		<!-- <input type="button" value="查找公众号 byType" onclick="searchPublicServiceByType();">  -->
		<input type="button" value="订阅公众号" onclick="subscribePublicService();"> 
		<input type="button" value="取消订阅公众号" onclick="unsubscribePublicService();"> 
		<input type="button" value="获取公众号信息" onclick="getPublicServiceProfile();"> 
		<input type="button" value="给公众号留言" onclick="sendToPublic();"> 
		<input type="button" value="公众号历史留言" onclick="getPublicHistroyMessage();"> 
	</div>
	<br>
</div>

<div class="result" id="result-area">
	<h3 id="result-title">运行结果：</h3>

	<div class="result-btns">
		<button id="collapse-btn">Collapse</button>
		<button id="expand-btn">Expand</button>
		<button id="toggle-btn">Toggle</button>
		<button id="toggle-level1-btn">Toggle level1</button>
		<button id="toggle-level2-btn">Toggle level2</button>
		
		<button class="result-code" id="result-code-btn">查看代码</button>
	</div>

	<div id="result-body"></div>
</div>


<ol id="show" class="show"></ol>
<div id="show1"></div>
<script>
(function(){
	var t = document.getElementById("btns");
	var _code = document.getElementById("result-code-btn");
	var _funcName = "", _btnName = "";
	t.onclick = function(event){
		var e = event || window.event;
		var node = e.target || e.srcElement;
		var tagName = node.tagName.toLowerCase();
		if(tagName == "input"){
			_funcName = node.getAttribute("onclick").split("(")[0];
			_btnName = node.innerHTML;
		}
	}
	_code.onclick = function(){
		var code = window[_funcName] + "";

		var start = new Date().getTime();
		showResult(_btnName, window[_funcName], start);
	}
})();
</script>

</body>
</html>